/*
 * Copyright 2002-2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.aop;

/**
 * Superinterface for advisors that perform one or more AOP <b>introductions</b>.
 *
 * <p>This interface cannot be implemented directly; subinterfaces must
 * provide the advice type implementing the introduction.
 *
 * <p>Introduction is the implementation of additional interfaces
 * (not implemented by a target) via AOP advice.
 *
 * @author Rod Johnson
 * @since 04.04.2003
 * @see IntroductionInterceptor
 */
/*
1.   接口总结
	IntroductionAdvisor 是 Spring AOP 中的一个接口，用于执行 AOP 引入（Introduction）。
	它继承自 Advisor 和 IntroductionInfo 接口，专门处理类型级别的增强，而不是方法级别(pointcut)的增强。
	此接口不能直接实现，必须通过其子接口提供具体的引入通知类型。

	类型引入功能：IntroductionAdvisor 是 Spring AOP 中专门用于执行类型引入（Introduction）的顾问接口，允许在运行时为目标对象动态添加新的接口及其实现。
	类级别增强：与 PointcutAdvisor 不同，IntroductionAdvisor 关注的是类级别的增强，不涉及方法匹配，而是通过 ClassFilter 来决定引入应该应用于哪些目标类。
	接口扩展机制：提供了一种机制，使得目标对象可以在运行时获得原本没有实现的接口功能，实现类似多重继承的效果

2. 内部成员方法说明
getClassFilter(): 返回决定该引入应该应用于哪些目标类的过滤器，代表切入点的类部分
validateInterfaces(): 验证被通知的接口是否可以由引入通知实现，在添加 IntroductionAdvisor 之前调用
3 相关的接口和类
Advisor (接口)
├── PointcutAdvisor (接口)
└── IntroductionAdvisor (接口)
    └── DefaultIntroductionAdvisor (实现类)
    └── DeclareParentsAdvisor (实现类)

 与相关接口的区别：
	Advisor: 最基础的顾问接口，定义了获取通知(Advice)的方法
	PointcutAdvisor: 扩展了 Advisor，增加了切入点(Pointcut)的概念，用于方法级别的匹配
	IntroductionAdvisor: 专门用于类型引入，不涉及方法匹配，只关注类级别的过滤

	IntroductionAdvisor和 PointcutAdvisor 的区别
	特性维度	IntroductionAdvisor	PointcutAdvisor
	增强级别	类级别，为整个类引入新接口	方法级别，增强特定方法
	核心元素	依赖 ClassFilter 识别目标类	依赖 Pointcut (含ClassFilter和MethodMatcher) 定位方法
	主要目的	引入新接口和方法	增强现有方法（如前置、后置通知）

4. 使用场景
	动态添加新接口实现：
		在运行时为目标对象动态地添加原本没有实现的新接口及其实现。
	无需修改原始类即可扩展功能：
		允许在不改变原有业务逻辑代码的前提下，向现有对象注入新的行为或状态。
	实现 Mixin 模式：
		利用引入机制，可以在多个对象之间共享某些通用功能，类似多重继承的效果。
	AOP 类型引入（Type Introduction）：
		特别适用于需要对一类对象统一添加某种能力的情况，例如安全检查、日志记录等辅助功能。

5. 实际代码应用示例
如下例子中，我们为目标对象引入了一个名为 Lockable 的接口，并提供了相应的实现。这样即使原对象并未实现这个接口，也可以通过代理对象访问这些新增的行为。
// 定义要引入的接口
public interface Lockable {
    void lock();
    void unlock();
    boolean isLocked();
}

// 实现该接口的通知类
class LockMixin implements Lockable, IntroductionInterceptor {
    private boolean locked;

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        if (isLocked() && invocation.getMethod().getName().equals("setAge")) {
            throw new RuntimeException("Object is locked");
        }
        return invocation.proceed();
    }

    @Override
    public boolean implementsInterface() {
        return true;
    }

    // 实现 Lockable 接口的方法
    public void lock() { this.locked = true; }
    public void unlock() { this.locked = false; }
    public boolean isLocked() { return this.locked; }
}

// 创建 IntroductionAdvisor 并将其应用到目标 bean 上
        // 创建目标对象
Person targetBean = new Person();
DefaultIntroductionAdvisor advisor = new DefaultIntroductionAdvisor(new LockMixin(), Lockable.class);
ProxyFactory factory = new ProxyFactory(targetBean);
factory.addAdvisor(advisor);
Object proxy = factory.getProxy();


 */
public interface IntroductionAdvisor extends Advisor, IntroductionInfo {

	/**
	 * Return the filter determining which target classes this introduction
	 * should apply to.
	 * <p>This represents the class part of a pointcut. Note that method
	 * matching doesn't make sense to introductions.
	 * @return the class filter
	 */
	ClassFilter getClassFilter();

	/**
	 * Can the advised interfaces be implemented by the introduction advice?
	 * Invoked before adding an IntroductionAdvisor.
	 * @throws IllegalArgumentException if the advised interfaces can't be
	 * implemented by the introduction advice
	 */
	void validateInterfaces() throws IllegalArgumentException;

}
